package org.gg.boom.modules.schedule.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.gg.boom.common.utils.ConvertUtils;
import org.gg.boom.kernel.config.factory.PageFactory;
import org.gg.boom.modules.schedule.mapper.ScheduleMapper;
import org.gg.boom.modules.schedule.model.dto.ScheduleJobDTO;
import org.gg.boom.modules.schedule.model.entity.ScheduleJobEntity;
import org.gg.boom.modules.schedule.utils.ScheduleConst;
import org.gg.boom.modules.schedule.utils.ScheduleUtils;
import org.quartz.Scheduler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Service
@AllArgsConstructor
public class ScheduleJobService extends ServiceImpl<ScheduleMapper, ScheduleJobEntity> {

    private final Scheduler scheduler;

    public Page<ScheduleJobDTO> page(Map<String, Object> params) {
        Page<ScheduleJobDTO> page = baseMapper.page(PageFactory.defaultPage(), params);
        return page;
    }

    public ScheduleJobDTO get(Long id) {
        ScheduleJobEntity entity = baseMapper.selectById(id);
        return ConvertUtils.sourceToTarget(entity, ScheduleJobDTO.class);
    }

    private QueryWrapper<ScheduleJobEntity> getWrapper(Map<String, Object> params) {
        String beanName = (String) params.get("beanName");

        QueryWrapper<ScheduleJobEntity> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(beanName), "bean_name", beanName);

        return wrapper;
    }

    @Transactional(rollbackFor = Exception.class)
    public void save(ScheduleJobDTO dto) {
        ScheduleJobEntity entity = ConvertUtils.sourceToTarget(dto, ScheduleJobEntity.class);

        entity.setStatus(ScheduleConst.ScheduleStatus.NORMAL.getValue());
        this.save(entity);

        ScheduleUtils.createScheduleJob(scheduler, entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(ScheduleJobDTO dto) {
        ScheduleJobEntity entity = ConvertUtils.sourceToTarget(dto, ScheduleJobEntity.class);

        ScheduleUtils.updateScheduleJob(scheduler, entity);

        this.updateById(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] ids) {
        for (Long id : ids) {
            ScheduleUtils.deleteScheduleJob(scheduler, id);
        }

        //删除数据
        baseMapper.deleteBatchIds(Arrays.asList(ids));
    }

    public int updateBatch(Long[] ids, int status) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("ids", ids);
        map.put("status", status);
        return baseMapper.updateBatch(map);
    }

    @Transactional(rollbackFor = Exception.class)
    public void run(Long[] ids) {
        for (Long id : ids) {
            ScheduleUtils.run(scheduler, baseMapper.selectById(id));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void pause(Long[] ids) {
        for (Long id : ids) {
            ScheduleUtils.pauseJob(scheduler, id);
        }

        updateBatch(ids, ScheduleConst.ScheduleStatus.PAUSE.getValue());
    }

    @Transactional(rollbackFor = Exception.class)
    public void resume(Long[] ids) {
        for (Long id : ids) {
            ScheduleUtils.resumeJob(scheduler, id);
        }

        updateBatch(ids, ScheduleConst.ScheduleStatus.NORMAL.getValue());
    }

}
